package org.example.mall.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.example.mall.entity.User;
import org.example.mall.mapper.UserMapper;
import org.example.mall.service.UserService;
import org.example.mall.utils.FileUploadUtil;
import org.example.mall.utils.MD5Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    private static final String VERIFICATION_CODE_PREFIX = "verification_code:";
    private static final int VERIFICATION_CODE_EXPIRE = 5; // 验证码有效期5分钟

    @Override
    public User registerByPhone(String phone, String verificationCode, String password) {
        // 这是一个简化版本，调用完整版本并使用默认值
        return registerByPhone(phone, verificationCode, password, null, null);
    }

    @Override
    public User registerByPhone(String phone, String verificationCode, String password, String email, MultipartFile avatar) {
        log.info("Start registering user with phone: {}", phone);

        // 验证手机号格式
        if (!isValidPhone(phone)) {
            log.error("Invalid phone number format: {}", phone);
            throw new IllegalArgumentException("手机号格式不正确");
        }

        // 验证验证码
        String cachedCode = redisTemplate.opsForValue().get(VERIFICATION_CODE_PREFIX + phone);
        log.debug("Cached verification code: {}, Provided code: {}", cachedCode, verificationCode);

        if (cachedCode == null) {
            log.error("Verification code not found or expired for phone: {}", phone);
            throw new IllegalArgumentException("验证码已过期，请重新获取");
        }

        if (!verificationCode.equals(cachedCode)) {
            log.error("Invalid verification code for phone: {}", phone);
            throw new IllegalArgumentException("验证码不正确");
        }

        // 验证密码格式
        if (!isValidPassword(password)) {
            log.error("Invalid password format for phone: {}", phone);
            throw new IllegalArgumentException("密码必须以大写字母开头，长度6-10位");
        }

        // 验证邮箱格式（如果提供）
        if (email != null && !isValidEmail(email)) {
            throw new IllegalArgumentException("邮箱格式不正确");
        }

        // 检查手机号是否已注册
        if (userMapper.selectByPhone(phone) != null) {
            log.error("Phone number already registered: {}", phone);
            throw new IllegalArgumentException("该手机号已注册");
        }

        try {
            // 创建新用户
            User user = new User();
            user.setPhone(phone);
            user.setPassword(MD5Utils.encrypt(password));
            user.setUsername(generateUsername());
            if (email != null) {
                user.setEmail(email);
            }
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            user.setStatus(1);

            // 处理头像上传
            if (avatar != null && !avatar.isEmpty()) {
                String avatarPath = FileUploadUtil.saveFile(avatar);
                user.setAvatar(avatarPath);
            }

            // 保存用户到数据库
            userMapper.insert(user);

            // 注册成功后删除验证码
            redisTemplate.delete(VERIFICATION_CODE_PREFIX + phone);

            log.info("Successfully registered user with phone: {}", phone);
            return user;
        } catch (Exception e) {
            log.error("Error while registering user with phone: {}", phone, e);
            throw new IllegalArgumentException("注册失败，请稍后重试");
        }
    }
    @Override
    public User register(String username, String password) {
        // 这是一个简化版本，调用完整版本并使用默认值
        return register(username, password, null, null);
    }
    @Override
    public User register(String username, String password, String email, MultipartFile avatar) {
        // 验证用户名格式
        if (!isValidUsername(username)) {
            throw new IllegalArgumentException("用户名必须是6-10位字母或数字");
        }

        // 验证密码格式
        if (!isValidPassword(password)) {
            throw new IllegalArgumentException("密码必须以大写字母开头，长度6-10位");
        }

        // 验证邮箱格式
        if (email != null && !isValidEmail(email)) {
            throw new IllegalArgumentException("邮箱格式不正确");
        }

        // 检查用户名是否已存在
        if (userMapper.selectByUsername(username) != null) {
            throw new IllegalArgumentException("该用户名已存在");
        }

        try {
            // 创建新用户
            User user = new User();
            user.setUsername(username);
            user.setPassword(MD5Utils.encrypt(password));
            if (email != null) {
                user.setEmail(email);
            }
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            user.setStatus(1);

            // 处理头像上传
            if (avatar != null && !avatar.isEmpty()) {
                String avatarPath = FileUploadUtil.saveFile(avatar);
                user.setAvatar(avatarPath);
            }

            // 保存用户到数据库
            userMapper.insert(user);

            return user;
        } catch (Exception e) {
            log.error("Error while registering user with username: {}", username, e);
            throw new IllegalArgumentException("注册失败，请稍后重试");
        }
    }

    @Override
    public User loginByPhone(String phone, String verificationCode) {
        // 验证手机号格式
        if (!isValidPhone(phone)) {
            throw new IllegalArgumentException("手机号格式不正确");
        }

        // 检查手机号是否已注册
        User user = userMapper.selectByPhone(phone);
        if (user == null) {
            throw new IllegalArgumentException("该手机号未注册");
        }

        // 验证验证码
        String cachedCode = redisTemplate.opsForValue().get(VERIFICATION_CODE_PREFIX + phone);
        if (cachedCode == null) {
            throw new IllegalArgumentException("验证码已过期，请重新获取");
        }

        if (!verificationCode.equals(cachedCode)) {
            throw new IllegalArgumentException("验证码不正确");
        }

        // 登录成功后删除验证码
        redisTemplate.delete(VERIFICATION_CODE_PREFIX + phone);

        return user;
    }

    @Override
    public User loginByPhonePassword(String phone, String password) {
        // 验证手机号格式
        if (!isValidPhone(phone)) {
            throw new IllegalArgumentException("手机号格式不正确");
        }

        // 检查手机号是否已注册
        User user = userMapper.selectByPhone(phone);
        if (user == null) {
            throw new IllegalArgumentException("该手机号未注册");
        }

        // 验证密码
        if (!user.getPassword().equals(MD5Utils.encrypt(password))) {
            throw new IllegalArgumentException("密码错误");
        }

        return user;
    }

    @Override
    public User login(String username, String password) {
        if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
            throw new IllegalArgumentException("用户名和密码不能为空");
        }

        // 从数据库获取用户信息
        User user = userMapper.selectByUsername(username);
        if (user == null) {
            throw new IllegalArgumentException("用户名不存在");
        }

        if (!user.getPassword().equals(MD5Utils.encrypt(password))) {
            throw new IllegalArgumentException("密码错误");
        }

        return user;
    }

    @Override
    public void sendVerificationCode(String phone) {
        log.info("Sending verification code to phone: {}", phone);

        if (!isValidPhone(phone)) {
            log.error("Invalid phone number format: {}", phone);
            throw new IllegalArgumentException("手机号格式不正确");
        }

        try {
            // 生成6位随机验证码
            String code = generateVerificationCode();

            // 将验证码保存到Redis，设置5分钟过期
            redisTemplate.opsForValue().set(
                    VERIFICATION_CODE_PREFIX + phone,
                    code,
                    VERIFICATION_CODE_EXPIRE,
                    TimeUnit.MINUTES
            );

            // 在控制台打印验证码，方便测试
            log.info("============================================");
            log.info("手机号: {}", phone);
            log.info("验证码: {}", code);
            log.info("有效期: {}分钟", VERIFICATION_CODE_EXPIRE);
            log.info("============================================");
        } catch (Exception e) {
            log.error("Error while sending verification code to phone: {}", phone, e);
            throw new IllegalArgumentException("发送验证码失败，请稍后重试");
        }
    }

    @Override
    public User updateUserInfo(Long userId, User userInfo) {
        // 验证用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }

        // 更新用户信息
        if (userInfo.getNickname() != null) {
            user.setNickname(userInfo.getNickname());
        }
        if (userInfo.getEmail() != null) {
            if (!isValidEmail(userInfo.getEmail())) {
                throw new IllegalArgumentException("邮箱格式不正确");
            }
            user.setEmail(userInfo.getEmail());
        }
        if (userInfo.getAvatar() != null) {
            user.setAvatar(userInfo.getAvatar());
        }

        user.setUpdateTime(LocalDateTime.now());

        // 保存到数据库
        userMapper.updateUserInfo(user);

        return user;
    }

    @Override
    public User updateUserInfo(Long userId, User userInfo, MultipartFile avatar) {
        // 验证用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }

        // 更新用户信息
        if (userInfo.getNickname() != null) {
            user.setNickname(userInfo.getNickname());
        }
        if (userInfo.getEmail() != null) {
            if (!isValidEmail(userInfo.getEmail())) {
                throw new IllegalArgumentException("邮箱格式不正确");
            }
            user.setEmail(userInfo.getEmail());
        }

        // 处理头像上传
        if (avatar != null && !avatar.isEmpty()) {
            try {
                String avatarPath = FileUploadUtil.saveFile(avatar);
                user.setAvatar(avatarPath);
            } catch (Exception e) {
                log.error("头像上传失败", e);
                throw new IllegalArgumentException("头像上传失败: " + e.getMessage());
            }
        }

        user.setUpdateTime(LocalDateTime.now());

        // 保存到数据库
        userMapper.updateUserInfo(user);

        return user;
    }

    @Override
    public boolean updatePassword(Long userId, String oldPassword, String newPassword) {
        // 验证用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }

        // 验证旧密码
        if (!user.getPassword().equals(MD5Utils.encrypt(oldPassword))) {
            throw new IllegalArgumentException("原密码错误");
        }

        // 验证新密码格式
        if (!isValidPassword(newPassword)) {
            throw new IllegalArgumentException("新密码必须以大写字母开头，长度6-10位");
        }

        // 更新密码
        return userMapper.updatePassword(
                userId,
                MD5Utils.encrypt(oldPassword),
                MD5Utils.encrypt(newPassword),
                LocalDateTime.now().toString()
        ) > 0;
    }

    @Override
    public User getUserById(Long userId) {
        if (userId == null || userId <= 0) {
            throw new IllegalArgumentException("用户ID不合法");
        }
        return userMapper.selectById(userId);
    }

    @Override
    public User getUserByPhone(String phone) {
        if (!isValidPhone(phone)) {
            log.error("Invalid phone number format: {}", phone);
            throw new IllegalArgumentException("手机号格式不正确");
        }
        return userMapper.selectByPhone(phone);
    }

    @Override
    public boolean isPhoneRegistered(String phone) {
        return userMapper.selectByPhone(phone) != null;
    }

    // 验证邮箱格式
    private boolean isValidEmail(String email) {
        return email != null && email.matches("^[A-Za-z0-9+_.-]+@(.+)$");
    }

    // 生成6位随机验证码
    private String generateVerificationCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    // 生成随机用户名
    private String generateUsername() {
        return "user" + System.currentTimeMillis() % 1000000;
    }

    // 验证手机号格式
    private boolean isValidPhone(String phone) {
        return phone != null && phone.matches("^1[3-9]\\d{9}$");
    }

    // 验证用户名格式
    private boolean isValidUsername(String username) {
        return username != null && username.matches("^[a-zA-Z0-9]{6,10}$");
    }

    // 验证密码格式
    private boolean isValidPassword(String password) {
        return password != null && password.matches("^[A-Z][a-zA-Z0-9]{5,9}$");
    }
}